import { CSSProperties, FC, ReactNode, useEffect, useState } from 'react'
import { Graph, Node } from '@antv/x6'
import { Image, Modal, Spin } from 'antd'
import styles from './ImageNode.module.scss'
import { useColorVar, useStyles } from '@/hooks/styles'
import { motion } from 'framer-motion'
import { baseUrl, motionEasing } from '@/config'
import { DeleteOutlined, EyeOutlined } from '@ant-design/icons'
import axios from 'axios'
import { useGraphStore } from '@/hooks'

interface IImageNode {
  node?: Node
  graph?: Graph
  imageID?: string
  url?: string
}

export const calcSortPos = (x: number) => {
  const start = 20
  const end = 1062
  return Math.round(((x - start) / (end - start)) * 100)
}

export const ImageNode: FC<IImageNode> = ({
  node,
  graph,
  imageID,
  url = 'https://s3.bmp.ovh/imgs/2024/02/02/f619d50f5aa7e08b.png',
}) => {
  const c = useColorVar()
  const styleClass = useStyles(styles)

  const graphStore = useGraphStore()
  const [ifHover, setIfHover] = useState<boolean>(false)
  const [previewOpen, setPreviewOpen] = useState(false)

  const [sortPos, setSortPos] = useState<number>(0)
  const [caption, setCaption] = useState<string>('')

  const getCaption = async () => {
    await axios
      .post(`${baseUrl}/image/caption`, { image_url: imageID })
      .then((res) => {
        console.log(res.data.data)
        setCaption(res.data.data)
        return
      })
      .catch((error) => {
        console.log('error', error)
      })
  }

  useEffect(() => {
    node && node.setData({ url: url }, { deep: false, silent: true })

    imageID &&
      node &&
      graph &&
      graph.on('node:moving', ({ e, x, y, node, view }) => {
        if (node.id === imageID && node.getData()['inTrack']) {
          // console.log(calcSortPos(node.position().x))
          setSortPos(calcSortPos(node.position().x))
          return
        }
      })

    node &&
      graph &&
      graph.on('node:moved', ({ e, x, y, node, view }) => {
        if (node.id === imageID && 'position' in node.getData()) {
          // 如果之前已被排序，则会被拖回原位置
          node.translate(
            node.getData()['position']['x'] - node.position().x,
            node.getData()['position']['y'] - node.position().y,
            { transition: { duration: 500, timing: 'easeOutCubic' } } // 动画选项
          )
        }
      })
  }, [])

  useEffect(() => {
    if (node && node.id === imageID && node.getData()['inTrack']) {
      // console.log(calcSortPos(node.position().x))
      setSortPos(calcSortPos(node.position().x))
    }
  }, [])

  useEffect(() => {
    if (previewOpen) {
      getCaption()
    }
  }, [previewOpen])

  return (
    <div {...styleClass(['layout'])}>
      <div
        {...styleClass(['content'])}
        onMouseEnter={() => setIfHover(true)}
        onMouseLeave={() => setIfHover(false)}
      >
        <Image
          src={url}
          width={68}
          height={68}
          preview={false}
          draggable={false}
          /* placeholder={
            <Image
              src={`${url}?x-oss-process=image/blur,r_50,s_50/quality,q_1/resize,m_mfit,h_100,w_100`}
              width={68}
              height={68}
              preview={false}
              draggable={false}
            />
          } */
          {...styleClass(['content-img'])}
        />
        <motion.div
          {...styleClass(['content-tools'])}
          initial={{ opacity: 0 }}
          animate={{ opacity: ifHover ? 1 : 0, y: ifHover ? -20 : -8 }}
          transition={{ ...motionEasing }}
        >
          <MiniButton
            onClick={() => {
              setPreviewOpen(true)
            }}
          >
            <EyeOutlined rev={null} {...styleClass(['content-tools-icon'])} />
          </MiniButton>
          <MiniButton
            onClick={() => {
              graphStore.removeImage(imageID)
            }}
          >
            <DeleteOutlined
              rev={null}
              {...styleClass(['content-tools-icon'])}
            />
          </MiniButton>
        </motion.div>
        <motion.div
          {...styleClass(['content-tips'])}
          initial={{ opacity: 0 }}
          animate={{
            opacity: node.getData()['inTrack'] ? 1 : 0,
            y: node.getData()['inTrack'] ? 28 : 12,
          }}
          transition={{ ...motionEasing }}
        >
          <div {...styleClass(['content-tips-text'])}>{sortPos}</div>
        </motion.div>
      </div>

      <div {...styleClass(['bg'])}></div>
      <Modal
        open={previewOpen}
        title={'Preview'}
        footer={null}
        onCancel={() => setPreviewOpen(false)}
      >
        <img alt="example" style={{ width: '100%' }} src={url} />
        <div {...styleClass(['temp'])}>
          {caption === '' && <Spin />}
          <div {...styleClass(['temp-text'])}>{caption}</div>
        </div>
      </Modal>
    </div>
  )
}

interface IMiniButton {
  style?: CSSProperties
  className?: string
  onClick?: () => void
  children?: ReactNode
}
const MiniButton: FC<IMiniButton> = ({
  style,
  className,
  onClick,
  children,
}) => {
  const c = useColorVar()
  const styleClass = useStyles(styles)

  return (
    <motion.div
      {...styleClass(['mini-button'])}
      transition={{ ...motionEasing }}
      onClick={(e) => {
        e.stopPropagation()
        onClick && onClick()
      }}
    >
      {children}
    </motion.div>
  )
}
